package com.fengq1.timeaxis;

import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.ssh.JschUtil;
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
public class Deployment {
    private final static String ip = "101.42.96.205";

    private final static String user = "root";

    private final static String pwd = "Zheng3016txy.";

    public static void main(String[] args) {
        String projectName = "time-axis";
        String warName = "time-axis.war";
        String projectPath = "/opt/apps/time-axis/";
        String warbakPath = "/opt/apps/time-axis/warbaks/";
        String warPath = "/opt/apps/time-axis/warbaks/time-axis.war";
        String targetPath = Deployment.class.getResource("/application.yml").getPath();
        if (!isOs_x()) {
            targetPath = targetPath.substring(1);
        }
        String pomPath = targetPath.substring(0, targetPath.lastIndexOf("target")) + "pom.xml";
        exeCmd("mvn clean install -f " + pomPath);
        File file = new File(targetPath.replace("classes/application.yml", warName));
        if (!file.exists()) {
            log.error("打包失败！");
            return;
        }
        Session session = null;
        try {
            session = JschUtil.getSession(ip, 22, user, pwd);
            ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp");
            sftp.connect();
            sftp.cd(warbakPath);
            try {
                sftp.rename(warPath, warPath + "_" + DateUtil.formatDateTime(new Date()));
            } catch (Exception e) {

            }
            log.info("开始上传文件！");
            try {
                sftp.put(targetPath.replace("classes/application.yml", warName), warbakPath);
            } catch (SftpException e) {
                e.printStackTrace();
                log.error("上传文件失败");
            }
            log.info("上传文件成功！");
            remoteExecute(session, "kill -9 `ps -ef | grep " + projectName + "| grep -v grep | awk '{print $2}'`");
            remoteExecute(session, "rm -rf  /opt/apps/" + projectName + "/webapps/" + projectName);
            remoteExecute(session, "rm -rf  /opt/apps/" + projectName + "/webapps/" + warName);
            remoteExecute(session, "cp /opt/apps/" + projectName + "/warbaks/" + projectName + ".war /opt/apps/" + projectName + "/webapps/" + projectName + ".war");
            remoteExecute(session, "cd " + projectPath + "bin" + "&&" + "sh /opt/apps/" + projectName + "/bin/startup.sh");
            remoteExecute(session, "tail -f /opt/apps/" + projectName + "/logs/catalina.out");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("部署失败！");
        } finally {
            session.disconnect();
        }
    }

    public static List<String> remoteExecute(Session session, String command) throws JSchException {
        log.info(">> {}", command);
        List<String> resultLines = new ArrayList<>();
        ChannelExec channel = null;
        try {
            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand(command);
            InputStream input = channel.getInputStream();
            channel.connect(10000);
            try {
                BufferedReader inputReader = new BufferedReader(new InputStreamReader(input));
                String inputLine = null;
                while ((inputLine = inputReader.readLine()) != null) {
                    log.info("   {}", inputLine);
                    resultLines.add(inputLine);
                }
            } finally {
                if (input != null) {
                    try {
                        input.close();
                    } catch (Exception e) {
                        log.error("JSch inputStream close error:", e);
                    }
                }
            }
        } catch (IOException e) {
            log.error("IOcxecption:", e);
        } finally {
            if (channel != null) {
                try {
                    channel.disconnect();
                } catch (Exception e) {
                    log.error("JSch channel disconnect error:", e);
                }
            }
        }
        return resultLines;
    }

    public static void exeCmd(String commandStr) {
        if (!isOs_x()) {
            commandStr = "cmd /c " + commandStr;
        }
        System.out.println(commandStr);
        BufferedReader br = null;
        try {
            Process p = Runtime.getRuntime().exec(commandStr);
            br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null) {
                log.info(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static boolean isOs_x() {
        return System.getProperty("os.name").contains("OS X");
    }
}